﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

using YouHP.Model;
using YouHP.DALFactory;
using YouHP.Utility;
using YouHP.BLL.MedicalGraph;

namespace YouHP.BLL
{
    public class PatientTreatmentBLL
    {
        #region 单件模式
        static PatientTreatmentBLL _Instance;

        public static PatientTreatmentBLL Instance
        {
            get
            {
                if (_Instance == null)
                {
                    _Instance = new PatientTreatmentBLL();
                }
                return _Instance;
            }
        }
        #endregion

        #region 病人治疗记录

        // 治疗提取后台绑定的该疾病治疗药物中的几个，如果没有，则提取用户自由更新的药物；
        public List<TreatmentHistoryInfo> GetBindingTreatmentList(int prId)
        {
            List<TreatmentHistoryInfo> returnTreatmentHistList = new List<TreatmentHistoryInfo>();

            List<TreatmentHistoryInfo> curUsedTreatmentList = GetAllCurUsedTreatments(prId);
            if (curUsedTreatmentList.Count == 0)
                return returnTreatmentHistList;

            // 获得用户所患疾病所绑定的治疗
            PatientRecordInfo prInfo = PatientBLL.Instance.GetPatientRecordInfoById(prId);
            List<DiseaseTreatmentInfo> bindingDiseaseTreatmentHistList = DiseaseBLL.Instance.GetDiseaseTreatmentList(prInfo.DiseaseId);

            if (bindingDiseaseTreatmentHistList == null ||
                bindingDiseaseTreatmentHistList.Count == 0)
            {
                returnTreatmentHistList.Add(curUsedTreatmentList[0]);
                return returnTreatmentHistList;
            }

            // 如果到这里，说明用户所患疾病有绑定的治疗，而且用户也指定了治疗，不过两者是不是一致还不清楚
            foreach (TreatmentHistoryInfo treatmentHist in curUsedTreatmentList)
            {
                foreach (DiseaseTreatmentInfo diseaseTreatmentInfo in bindingDiseaseTreatmentHistList)
                {
                    if (treatmentHist.TreatmentId == diseaseTreatmentInfo.TreatmentId)
                    {
                        returnTreatmentHistList.Add(treatmentHist);

                        if (returnTreatmentHistList.Count >= 2)
                            return returnTreatmentHistList;

                        break;
                    }
                } // foreach
            } // foreach

            if (returnTreatmentHistList.Count > 0)
                return returnTreatmentHistList;

            returnTreatmentHistList.Add(curUsedTreatmentList[0]);
            return returnTreatmentHistList;
        }

        /*获取病人针对某种疾病当前使用的治疗所有列表*/
        public List<TreatmentHistoryInfo> GetAllCurUsedTreatments(int prId)  /*prId表示病人疾病纪录id*/
        {
            return DataAccess.PatientTreatmentDAL.GetUsingTreatmentList(prId);
        }

        /*获取病人针对某种疾病当前没有使用的治疗所有列表*/
        public List<TreatmentHistoryInfo> GetAllCurNoUsedTreatments(int prId)  /*prId表示病人疾病纪录id*/
        {
            return DataAccess.PatientTreatmentDAL.GetNoUsingTreatmentList(prId);
        }

        /*获取病人针对某种疾病所有治疗历史列表（包括当前正使用以及停止使用的）*/
        public List<TreatmentHistoryInfo> GetAllCurTreatments(int prId)  /*prId表示病人疾病纪录id*/
        {
            return DataAccess.PatientTreatmentDAL.GetAllCurTreatments(prId);
        }

#if GENDATA
        /*获取病人针对某种疾病使用某种治疗的分页历史纪录*/
        public List<TreatmentHistoryInfo> GetUseHistoryTreatments(int pageSize, int pageIndex, int prId, int tId, out int count)  /*prId表示病人疾病纪录id*/
        {
            count = 100;
            List<TreatmentHistoryInfo> lst = new List<TreatmentHistoryInfo>();
            TreatmentHistoryInfo info;

            info = new TreatmentHistoryInfo();
            info.StartDate = Convert.ToDateTime("2007-06-08");
            info.EndDate = Convert.ToDateTime("2007-09-22");
            info.Unit = "毫克";
            info.UsePurpose = 1;
            info.StopReason = 2;
            info.DataValue = 15;
            lst.Add(info);            

            return lst;

            return DataAccess.PatientTreatmentDAL.GetTreatmentHistoryList(prId, tId, pageSize, pageIndex,  out count);
        }
#else
        public List<TreatmentHistoryInfo> GetUseHistoryTreatments(int pageSize, int pageIndex, int prId, int tId, out int count)  /*prId表示病人疾病纪录id*/
        {
            return DataAccess.PatientTreatmentDAL.GetTreatmentHistoryList(pageSize, pageIndex,  prId, tId, out count);
        }
#endif

        /*获取病人针对某种疾病使用某种治疗的所有历史纪录*/
        public List<TreatmentHistoryInfo> GetAllUseHistoryTreatments(int prId, int tId)  /*prId表示病人疾病纪录id*/
        {
            int count = 0;
            return GetUseHistoryTreatments(Constants.maxPageSize, 1, prId, tId, out count);
        }

        /// <summary>
        /// 取得病人所有的治疗记录历史（根据察看模式）
        /// </summary>
        public List<TreatmentHistoryInfo> GetTreatementHistoryList(int prId, int viewMode)
        {
            DateTime minDate = new DateTime(1900, 1, 1);
            List<TreatmentHistoryInfo> trmLst = null;

            switch (viewMode)
            {
                case Constants.WEEKMODE:
                    break;
                case Constants.MONTHMODE:
                    break;
                case Constants.THREEMONTHMODE:
                    break;
                case Constants.YEARMODE:
                    break;
                case Constants.ALLMODE:
                default:
                    trmLst = DataAccess.PatientTreatmentDAL.GetTreatmentHistoryList(prId, minDate, DateTime.Now);
                    break;
            }

            return trmLst;
        }

        //判断历史记录表中是否已存在病人指定时间对应的记录
        public bool CheckTreatmentHistory(int prId, int treatmentId, DateTime actionDate)
        {
            return DataAccess.PatientTreatmentDAL.CheckTreatmentHistory(prId, treatmentId, actionDate);
        }

        /*添加治疗信息*/
        public bool AddTreatmentRecorde(TreatmentHistoryInfo info)
        {
            return DataAccess.PatientTreatmentDAL.AddTreatmentHistory(info);
        }

        /*开始新的治疗*/
        public bool StartTreatmentHistory(TreatmentHistoryInfo info)
        {
            return DataAccess.PatientTreatmentDAL.StartTreatmentHistory(info);
        }

        /*修改治疗信息*/
        public bool UpdateTreatmentRecorde(TreatmentHistoryInfo ptInfo)
        {
            return DataAccess.PatientTreatmentDAL.UpdateTreatmentHistory(ptInfo);
        }

        /*停止治疗信息*/
        public bool StopTreatmentRecorde(TreatmentHistoryInfo ptInfo)
        {
            return DataAccess.PatientTreatmentDAL.StopTreatmentHistory(ptInfo);
        }

        /*改变剂量*/
        public bool ChangeTreatmentDosage(TreatmentHistoryInfo ptInfo)
        {
            return DataAccess.PatientTreatmentDAL.ChangeTreatmentDosage(ptInfo);
        }

        /*批量删除治疗信息*/
        public bool DelTreatmentRecorde(int prId, int trId)
        {
            return DataAccess.PatientTreatmentDAL.DelTreatmentHistory(prId, trId);
        }

        // 获取当前治疗
        public TreatmentHistoryInfo GetCurrentTreatment(int prId, int trmId)
        {
            return DataAccess.PatientTreatmentDAL.GetCurrentTreatment(prId, trmId);
        }

        // 获取治疗的某条历史记录
        public TreatmentHistoryInfo GetTreatmentRecorde(int prId, int historyId)
        {
            return DataAccess.PatientTreatmentDAL.GetTreatmentHistory(prId, historyId);
        }

        // 获取某种治疗的历史纪录
        public List<TreatmentHistoryInfo> GetTreatmentHistoryList(int pageSize, int pageIndex, int prId, int trId, out int count)
        {
            return DataAccess.PatientTreatmentDAL.GetTreatmentHistoryList(pageSize, pageIndex, prId, trId, out count);
        }

        //获得某种治疗的所有历史记录
        public List<TreatmentHistoryInfo> GetTreatmentHistoryList(int prId, int trId)
        {
            return DataAccess.PatientTreatmentDAL.GetTreatmentHistoryList(prId, trId);
        }

        private List<int> GetBestFitPatientRecordIdsByTreatmentsCount(List<int> bestFitPrIds,
            Dictionary<int, int> PrIdAndTreatmentsCount)
        {
            int minimumTreatmentCount = 10000;

            foreach (KeyValuePair<int, int> pair in PrIdAndTreatmentsCount)
            {
                if (bestFitPrIds.Contains(pair.Key) && pair.Value < minimumTreatmentCount)
                {
                    minimumTreatmentCount = pair.Value;
                }
            }

            List<int> returnBestFitPrIds = new List<int>();

            foreach (KeyValuePair<int, int> pair in PrIdAndTreatmentsCount)
            {
                if (bestFitPrIds.Contains(pair.Key) && pair.Value == minimumTreatmentCount)
                {
                    returnBestFitPrIds.Add(pair.Key);
                }
            }

            return returnBestFitPrIds;
        }

        // 获取和当前病人使用相同治疗的病人，或者使用最接近的治疗的病人
        public List<UserInfo> GetBestFitTreatmentsPatientList(int prId)
        {   
            // 首先获得该病人当前正在使用的所有治疗
            List<TreatmentHistoryInfo> treatments = GetAllCurUsedTreatments(prId);

            // 如果用户当前没有使用任何治疗，结束
            int treatmentsCount = treatments.Count;
            if (treatmentsCount == 0)
                return null;

            Dictionary<int, int> PrIdAndTreatmentsCount = new Dictionary<int, int>();
            Dictionary<int, int> PrIdAndFitTreatmentCount = new Dictionary<int, int>();

            int maximumFitTreatmentsCounts = 0;

            foreach (TreatmentHistoryInfo treatment in treatments)
            {
                int treatmentId = treatment.TreatmentId;
                List<TreatmentHistoryInfo> records 
                    = DataAccess.PatientTreatmentDAL.GetCurrentTreatmentListByTreatmentId(treatmentId);

                foreach (TreatmentHistoryInfo record in records)
                {
                    if (record.PRId == prId)    // 自己
                        continue;

                    int otherPrId = record.PRId;
                    // BUG!!! 存储过程[GetCurrentTreatmentList]应该返回IsUsing这个字段
                    //if (record.IsUsing <= 0)    // 目前不在用
                    //    continue;

                    if (PrIdAndFitTreatmentCount.ContainsKey(otherPrId))
                    {
                        PrIdAndFitTreatmentCount[otherPrId]++;
                    }
                    else
                    {
                        PrIdAndFitTreatmentCount.Add(otherPrId, 1);
                    }

                    if (PrIdAndFitTreatmentCount[otherPrId] > maximumFitTreatmentsCounts)
                        maximumFitTreatmentsCounts = PrIdAndFitTreatmentCount[otherPrId];

                    if (!PrIdAndTreatmentsCount.ContainsKey(otherPrId))
                    {
                        List<TreatmentHistoryInfo> localTreatments = GetAllCurUsedTreatments(otherPrId);
                        if (localTreatments != null)
                            PrIdAndTreatmentsCount.Add(otherPrId, localTreatments.Count);
                    }
                } // foreach
            } // foreach

            // 没有任何匹配的，返回null
            if (maximumFitTreatmentsCounts == 0)
                return null;

            // 以匹配的治疗数目为唯一标准
            List<int> returnBestFitPrIds = new List<int>();

            if (treatmentsCount == maximumFitTreatmentsCounts)
            {
                // 当前用户拥有的治疗，有其他病友完全匹配之，找到治疗数目一致的优先返回
                foreach (KeyValuePair<int, int> pair in PrIdAndFitTreatmentCount)
                {
                    if (pair.Value == maximumFitTreatmentsCounts)
                    {
                        if (PrIdAndTreatmentsCount[pair.Key] == maximumFitTreatmentsCounts)
                            returnBestFitPrIds.Add(pair.Key);
                    }
                }

                if (returnBestFitPrIds.Count == 0)
                {
                    // bestFitPatientsPrIds为空，填充之
                    foreach (KeyValuePair<int, int> pair in PrIdAndFitTreatmentCount)
                    {
                        if (PrIdAndFitTreatmentCount[pair.Key] == maximumFitTreatmentsCounts)
                            returnBestFitPrIds.Add(pair.Key);
                    }

                    returnBestFitPrIds = GetBestFitPatientRecordIdsByTreatmentsCount(returnBestFitPrIds, PrIdAndTreatmentsCount);
                }

            }   // 如果其他病友能完全匹配当前病人的所有治疗
            else if (treatmentsCount > maximumFitTreatmentsCounts)
            {
                // 如果当前用户的所有治疗不能完全被其他用户匹配,
                // 找到匹配治疗的一个最大子集
                foreach (KeyValuePair<int, int> pair in PrIdAndFitTreatmentCount)
                {
                    if (pair.Value == maximumFitTreatmentsCounts)
                    {
                        returnBestFitPrIds.Add(pair.Key);
                    }
                }
            }
            else
            {
                // 不可能发生
                return null;
            }

            if (returnBestFitPrIds.Count == 0)
            {
                // 好像不可能发生
                return null;
            }

            List<UserInfo> returnBestFitPatientsList = new List<UserInfo>();

            for (int index = 0; index < returnBestFitPrIds.Count; index++)
            {
                int localPrId = returnBestFitPrIds[index];
                PatientRecordInfo prInfo = PatientBLL.Instance.GetPatientRecordInfoById(localPrId);
                UserInfo userInfo = UserBLL.Instance.GetUserInfo(prInfo.PatientId);
                returnBestFitPatientsList.Add(userInfo);
            }

            return returnBestFitPatientsList;
        }   // GetBestFitTreatmentsPatientList

        #endregion    
    }
}
